import React, { PureComponent } from 'react';
// 引入样式
import './scss/reader.scss';
// 引入请求
import Axios from 'axios';
// 引入地址
import { webSite } from '../../website';
// 引入框架
import { message, Modal, Drawer } from 'antd';
import {
  LeftOutlined,
  UnorderedListOutlined,
  CheckOutlined
} from '@ant-design/icons';
// 引入仓库
import store from '../../store/index';
//防抖方法
function debounce (fn, ms = 500) {
  let timeoutId
  return function () {
    clearTimeout(timeoutId)
    timeoutId = setTimeout(() => {
      fn.apply(this, arguments)
    }, ms)
  }
}
export default class Reader extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      // 标题
      novelTitle: '',
      // 内容
      novelText: '',
      // 所有章节的链接
      novelUrl: '',
      // 当前是第几章
      index: 0,
      // 章节目录
      getNovelAll: [],
      // 设置的对话框
      visible: false,
      // 字体大小
      TextSize: 22,
      // 背景颜色
      back: '#c5b49a',
      // 书签
      BookMark: [],
      // 切换
      isBackColor: false,
      // 字体颜色
      color: '#474c51',
      // 控制抽屉的显示隐藏
      NovelMVisible: false,
      // 控制书签的显示隐藏
      bookVisible: false
    }
    this.isPhoneLegal = debounce(this.isPhoneLegal, 1000)    // 调用的防抖
    // state的写法
    this.unSubscribe = store.subscribe(() => {
      // 强制更新
      this.forceUpdate()
    })
  }

  componentWillUnmount () {
    this.unSubscribe()
    // 卸载异步操作设置状态
    this.setState = () => {
      return;
    }
  }

  componentDidMount () {
    // 判断是否登录，登录之后获取用户信息
    this.getReaderSetUp();
    let { index, Font } = this.props.location.state;
    this.setState({
      // 设置index为当前章节
      index
    }, () => {
      // 组件传过来的对象的 URL
      let url = Font.novelUrl;
      // 根据url获取章节内容
      this.getReaderCon(url);
      // 当页面内容加载中完成时在自动加载所有的目录
      this.getNovelAllFun()
    })
  }

  // 同步用户的章节到用户账号
  novelWith = () => {
    let { getNovelAll, index } = this.state;
    let { userId } = store.getState().reducer;
    let { id } = this.props.location.state.Font;
    if (!userId) {
      // 用户没有登录跳转到首页
      this.props.history.replace('/')
      return;
    }
    // 需要 用户id  书的id  书第几页的链接  第几页的index 
    // 当id不为空  或者 不是第一章   或者 章节小于总章节长度时才存储服务器
    if (index >= 0) {
      if (id !== undefined) {
        Axios.create({
          baseURL: `${webSite}:3003`
        }).post("/synchronizationNovel", { id: userId, novelid: id, novelUrl: getNovelAll[index].novelUrl, index }).then(err => {
          if (err.data.code === 'S0001') {
            return;
          }
        }).catch(() => {
          message.error({ content: '网络错误', className: 'bulletChatMessage' });
        })
      }
    }
  }

  // 获取用户的所有配置信息
  getReaderSetUp = () => {
    // 先获取用户id根据用户id来获取用户的所有配置
    let { userId } = store.getState().reducer;
    let { id } = this.props.location.state.Font;
    if (!userId) {
      // 用户没有登录跳转到首页
      this.props.history.replace('/novel')
      return;
    }
    // 传一个用户id一个书的id
    if (id !== undefined) {
      Axios.create({
        baseURL: `${webSite}:3003`
      }).post("/getReaderSetUp", { id: userId, novelid: id }).then(err => {
        if (err.data.code === 'G0001') {
          // 获取仓库的设置信息
          let { size, back } = err.data.data;
          let BookMark = err.data.BookMark;
          this.setState({
            // 设置字体
            TextSize: size,
            // 设置背景
            back,
            // 设置书签
            BookMark
          })
        }
      }).catch(() => {
        message.error({ content: '网络错误', className: 'bulletChatMessage' });
      })
    }
  }

  // 获取章节目录
  getNovelAllFun = () => {
    // 获取几千张的目录  是全程序加载最慢的地方
    let novelUrl = this.props.location.state.novelHref;
    Axios.create({
      baseURL: `${webSite}:3003`
    }).post("/getnovelFont", { novelUrl }).then(err => {
      if (err.data.code === 'F0001') {
        this.setState({
          getNovelAll: err.data.novelFontAll
        })
      }
    }).catch(() => {
      message.error({ content: '网络错误', className: 'bulletChatMessage' });
    })
  }

  // 通过url获取内容
  getReaderCon = (url, blo = false) => {
    // 任何地方调用并传入值都可以获取到地址对应的内容
    Axios.create({
      baseURL: `${webSite}:3003`
    }).post("/getReader", { url }).then(err => {
      if (err.data.code === 'T0001') {
        // 标题
        let novelTitle = err.data.novelTitle;
        // 内容
        let novelText = err.data.novelText;
        // 章节的链接
        let novelUrl = err.data.novelUrl;
        this.setState({
          novelTitle,
          novelText,
          novelUrl
        }, () => {
          if (blo) {
            // 内容的总高度
            let readerCon = document.getElementById('reader_ConId').offsetHeight;
            // 页面加载完成给上方留空
            let readerBody = document.getElementById('reader_bodyId');
            readerBody.scrollTo(0, readerCon - 1000);
          } else {
            // 页面加载完成给上方留空
            let readerBody = document.getElementById('reader_bodyId');
            readerBody.scrollTo(0, 40);
          }
        })
      }
    }).catch(() => {
      message.error({ content: '网络错误', className: 'bulletChatMessage' });
    })
  }

  // 移动电子书
  readerBodyTop = () => {
    const _this = this;
    let { index, getNovelAll } = this.state;
    // 防止数据目录来不及加载时报错
    if (getNovelAll.length === 0) {
      return;
    }
    // 页面滚动的高度
    let readerBody = document.getElementById('reader_bodyId').scrollTop;
    // 可滚动页面的高度
    let readerHerght = document.getElementById('reader_bodyId').offsetHeight;
    // 内容的总高度
    let readerCon = document.getElementById('reader_ConId').offsetHeight;
    if (readerCon < readerHerght) {
      // 这里是当页面不足一页时触发的函数
      function add () {
        // 下一章
        if (index < getNovelAll.length - 1) {
          if (index >= 0) {
            // 加载中 logo
            message.success({ content: '下一章加载中', className: 'LoadingNextChapter', duration: 1, style: { marginTop: '150vw' } })
            let url = getNovelAll[index + 1].novelUrl;
            // 用下一页的 URL 对应的内容渲染页面
            _this.getReaderCon(url);
          }
          // 章节数加 1 并重新调用内容
          _this.setState({
            index: index + 1
          }, () => {
            // 把章节存储到账号
            _this.novelWith()
          })
        } else {
          message.error({ content: '这是最新的一章', className: 'bulletChatMessage' });
          // 把章节存储到账号
          _this.novelWith()
        }
      }
      // 这里是防抖
      this.isPhoneLegal(add)
    } else {
      if (readerBody + 700 >= readerCon) {
        function add () {
          // 下一章
          if (index < getNovelAll.length - 1) {
            // 当滑动条拖到底时 index 加 1 
            if (index >= 0) {
              // 加载中的logo
              message.success({ content: '下一章加载中', className: 'LoadingNextChapter', duration: 1, style: { marginTop: '150vw' } })
              // 把下一章新的 内容渲染到页面上
              let url = getNovelAll[index + 1].novelUrl;
              _this.getReaderCon(url);
            }
            _this.setState({
              index: index + 1
            }, () => {
              // 把章节存储到账号
              _this.novelWith()
            })
          } else {
            message.error({ content: '这是最新的一章', className: 'bulletChatMessage' });
            // 把章节存储到账号
            _this.novelWith()
          }
        }
        // 防抖函数
        this.isPhoneLegal(add)
      }
      if (readerBody === 0) {
        function add () {
          // 上一章
          if (index > 0) {
            // 调用上一章时减 1 
            // 不能让index 大于 数组的总长度
            if (index <= getNovelAll.length) {
              // 上一章加载的 logo
              message.success({ content: '上一章加载中', className: 'LoadingNextChapter', duration: 1, style: { marginTop: '1vw' } })
              // 上一章重新调用一下
              let url = getNovelAll[index - 1].novelUrl;
              _this.getReaderCon(url, true);
            }
            _this.setState({
              index: index - 1
            }, () => {
              // 把章节存储到账号
              _this.novelWith()
            })
          } else {
            message.error({ content: '前面没有了', className: 'bulletChatMessage' });
            // 把章节存储到账号
            _this.novelWith()
          }
        }
        // 防抖函数
        this.isPhoneLegal(add)
      }
    }
  }

  isPhoneLegal = (fn) => {
    fn()  // 防抖后获取的值
  }

  // 点击弹出设置
  showModal = () => {
    this.setState({
      visible: true,
    });
  };

  // 关闭对话框
  handleCancel = () => {
    this.setState({
      visible: false,
    });
  };

  // 返回书首页
  goHomeNovel = () => {
    this.props.history.replace('/novel')
  }

  // 设置字体大小
  ConsetSize = (bol) => {
    let { TextSize } = this.state;
    if (bol) {
      this.setState({
        TextSize: TextSize + 1
      })
    } else {
      this.setState({
        TextSize: TextSize - 1
      })
    }
    // 同步到账号
    this.setBackSize()
  }

  // 设置背景颜色
  SetBackCon = (backColor) => {
    this.setState({
      back: backColor
    })
    // 同步到账号
    this.setBackSize()
  }

  setBackSize = () => {
    let { getNovelAll, TextSize, back } = this.state;
    let { id } = this.props.location.state.Font;
    if (getNovelAll.length !== 0 && id !== undefined) {
      // 当前用户的id
      let { userId } = store.getState().reducer;
      Axios.create({
        baseURL: `${webSite}:3003`
      }).post("/setBackSize", { id: userId, novelset: { size: TextSize, back } }).then(err => {
        if (err.data.code === 'A0001') {
          return;
        }
      }).catch(() => {
        message.error({ content: '网络错误', className: 'bulletChatMessage' });
      })
    }
  }

  // 切换日夜模式
  isBackColor = (bol, back, color) => {
    this.setState({
      isBackColor: bol,
      back,
      color
    })
  }

  // 开启抽屉目录
  showDrawer = () => {
    // 跳转目录到当前章节
    let { index, getNovelAll } = this.state;
    if (getNovelAll.length !== 0 && document.getElementById('DrawerBodyUlId')) {
      // 内容的总高度
      let readerCon = document.getElementById('DrawerBodyUlId').offsetHeight;
      let readerBody = document.getElementById('DrawerBodyId');
      // 把进度定位到内容高度
      let scroHeight = readerCon * (index / getNovelAll.length);
      readerBody.scrollTo(0, scroHeight - 200);
    }
    this.setState({
      NovelMVisible: true,
    });
  };

  // 关闭抽屉目录
  onClose = () => {
    this.setState({
      NovelMVisible: false,
    });
  };

  // 关闭书签
  onCloseBook = () => {
    this.setState({
      bookVisible: false,
    });
  };

  // 开启书签
  showDrawerBook = () => {
    // 请求一次书签数据
    this.getBookMarjAll()
    this.setState({
      bookVisible: true,
    });
  }

  // 跳转章节
  ClickGoNovel = (url, index) => {
    this.getReaderCon(url);
    this.setState({
      index,
      // 关闭抽屉
      NovelMVisible: false,
      // 关闭设置
      visible: false
    }, () => {
      // 存入设置
      this.novelWith()
    })
  }

  // 添加书签
  addBookmark = () => {
    let { index, getNovelAll } = this.state;
    let { id } = this.props.location.state.Font;
    if (getNovelAll.length !== 0 && id !== undefined) {
      // 获取进度
      let scroHeight = (index / getNovelAll.length).toFixed(2) * 100 + '%';
      // 获取时间戳
      let timestamp = Math.round(new Date() / 1000);
      // 当前页面的url
      let url = getNovelAll[index].novelUrl;
      // 当前的标题
      let text = getNovelAll[index].novelText;
      // 当前用户的id
      let { userId } = store.getState().reducer;
      let bookMarkObj = {
        scroHeight,
        timestamp,
        index,
        url,
        text
      }
      Axios.create({
        baseURL: `${webSite}:3003`
      }).post("/addBookmark", { id: userId, bookMarkObj, novelid: id }).then(err => {
        if (err.data.code === 'D0001') {
          message.success({ content: '书签添加成功', className: 'bulletChatMessage' })
        } else {
          message.success({ content: '网络错误暂时无法添加', className: 'bulletChatMessage' })
        }
      }).catch(() => {
        message.error({ content: '网络错误', className: 'bulletChatMessage' });
      })
    } else {
      // 用户没有书就提示用户
      message.success({ content: '您需要先添加书籍到书架', className: 'bulletChatMessage' })
    }
  }

  // 获取书架信息
  getBookMarjAll = () => {
    let { getNovelAll } = this.state;
    let { id } = this.props.location.state.Font;
    if (getNovelAll.length !== 0 && id !== undefined) {
      // 当前用户的id
      let { userId } = store.getState().reducer;
      Axios.create({
        baseURL: `${webSite}:3003`
      }).post("/getBookmarkAll", { id: userId, novelid: id }).then(err => {
        this.setState({
          BookMark: err.data.BookMark
        })
      })
    }
  }

  // 点击书签跳转到对应页面
  ClickBookIndex = (url, index) => {
    this.getReaderCon(url);
    this.setState({
      index,
      // 关闭书签
      bookVisible: false,
      // 关闭设置
      visible: false
    }, () => {
      // 存入设置
      this.novelWith()
    })
  }
  render () {
    let { novelText, novelTitle, TextSize, back, isBackColor, color, NovelMVisible, visible, getNovelAll, bookVisible, BookMark } = this.state;
    let int = this.state.index;
    function getLocalTime (nS) {
      return new Date(parseInt(nS) * 1000).toLocaleString().replace(/年|月/g, "-").replace(/日/g, " ");
    }
    return (
      <div className='reader'>
        {/* 书签 */}
        <Drawer
          placement='right'
          closable={false}
          onClose={this.onCloseBook}
          visible={bookVisible}
          getContainer={() => document.getElementsByClassName('reader')[0]}
          className='bookDrawer'
        >
          <h3>书签</h3>
          <ul className='bookDrawer_body'>
            {
              BookMark.length !== 0 ?
                BookMark.map((list, index) => {
                  return (
                    <li key={index} onClick={() => this.ClickBookIndex(list.url, list.index)}>
                      <div className='bookDrawer_body_con' dangerouslySetInnerHTML={{ __html: list.text }}></div>
                      <div className='bookDrawer_body_time'>
                        <h4>{list.scroHeight}</h4>
                        <h4 style={{ width: '70%' }}>{getLocalTime(list.timestamp)}</h4>
                      </div>
                    </li>
                  )
                })
                : <li>您还有有添加书签</li>
            }
          </ul>
        </Drawer>
        {/* 目录抽屉 */}
        <Drawer
          placement='left'
          closable={false}
          onClose={this.onClose}
          visible={NovelMVisible}
          getContainer={() => document.getElementsByClassName('reader')[0]}
          className='readerDrawer'
        >
          <h3>目录</h3>
          <div className='readerDrawer_body' id='DrawerBodyId'>
            <ul id='DrawerBodyUlId'>
              {
                getNovelAll.length !== 0 ?
                  getNovelAll.map((list, index) => {
                    return (
                      <li key={index} dangerouslySetInnerHTML={{ __html: list.novelText }} onClick={() => this.ClickGoNovel(list.novelUrl, index)} className={index === int ? 'border' : ''}></li>
                    )
                  })
                  : <li>章节目录加载中......</li>
              }
            </ul>
          </div>
        </Drawer>
        {/* 底部设置 */}
        <Modal
          visible={visible}
          onCancel={this.handleCancel}
          footer={null}
          getContainer={() => document.getElementsByClassName('reader')[0]}
          className='readerBoxSeet'
          centered={true}
          bodyStyle={{
            width: '100%',
            height: '100%',
            padding: '0'
          }}
        >
          {/* 设置字体大小 */}
          <div className='readerBoxSeet_body_size'>
            <div className='readerBoxSeet_body_size_jian' onClick={() => this.ConsetSize(false)}>
              A-
            </div>
            <div className='readerBoxSeetBodySize'>
              {TextSize}
            </div>
            <div className='readerBoxSeet_body_size_jia' onClick={() => this.ConsetSize(true)}>
              A+
            </div>
          </div>
          {/* 设置颜色 */}
          <ul className='readerBoxSeetBodyBack'>
            <li style={{ background: '#c5b49a' }} onClick={() => this.SetBackCon('#c5b49a')}>
              {
                back === '#c5b49a' ?
                  <CheckOutlined className='readerBoxSeetBodyBack_check' />
                  : ''
              }
            </li>
            <li style={{ background: '#cad9e8' }} onClick={() => this.SetBackCon('#cad9e8')}>
              {
                back === '#cad9e8' ?
                  <CheckOutlined className='readerBoxSeetBodyBack_check' />
                  : ''
              }
            </li>
            <li style={{ background: '#d1edd1' }} onClick={() => this.SetBackCon('#d1edd1')}>
              {
                back === '#d1edd1' ?
                  <CheckOutlined className='readerBoxSeetBodyBack_check' />
                  : ''
              }
            </li>
            <li style={{ background: '#e6e6e6' }} onClick={() => this.SetBackCon('#e6e6e6')}>
              {
                back === '#e6e6e6' ?
                  <CheckOutlined className='readerBoxSeetBodyBack_check' />
                  : ''
              }
            </li>
          </ul>
          <ul className='readerBoxSeetBodyBackBottom'>
            <li>
              <UnorderedListOutlined className='readerBoxSeetBodyBackBottom_unorder' onClick={this.showDrawer} />
              <p>目录</p>
            </li>
            <li>
              <img src={require('./image/jia.png')} alt="添加书签" width='23' onClick={this.addBookmark} />
              <p>添加书签</p>
            </li>
            <li>
              <img src={require('./image/shujia.png')} alt="书架" width='30' onClick={this.goHomeNovel} />
              <p>书架</p>
            </li>
            {
              isBackColor ?
                <li onClick={() => this.isBackColor(false, '#c5b49a', '#474c51')}>
                  <img src={require('./image/ri.png')} alt="日" width='25' />
                  <p>日间</p>
                </li>
                :
                <li onClick={() => this.isBackColor(true, '#1a1a1a', '#ffffff80')}>
                  <img src={require('./image/ye.png')} alt="野" width='25' />
                  <p>夜间</p>
                </li>
            }
          </ul>
          {/* 顶部点击 */}
          <div className='readerBoxSeetBodyBackTop'>
            <LeftOutlined className='readerBoxSeetBodyBackTopHome' onClick={this.goHomeNovel} />
            <img src={require('./image/all.png')} alt="所有书签" width='25' onClick={this.showDrawerBook} />
          </div>
        </Modal>
        <div className='reader_h3' style={{ background: back }}><h3 style={{ color }} dangerouslySetInnerHTML={{ __html: novelTitle }} ></h3></div>
        <div className='reader_body' id='reader_bodyId' onTouchMove={this.readerBodyTop} onClick={this.showModal} style={{ background: back, color }}>
          <h3 style={{ color }} dangerouslySetInnerHTML={{ __html: novelTitle }} className='textHrem'></h3>
          <div className='reader_body_const' id='reader_ConId' dangerouslySetInnerHTML={{ __html: novelText }} style={{ fontSize: TextSize }}></div>
        </div>
      </div>
    )
  }
}